package crawler;

import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

import parser.ParserAnnotation;
import parser.ParserPipeline;
import asa.PostBucket;

import forum.ForumFactory;
import forum.ForumPost;
import forum.ForumTag;

public class BugCrawler extends Crawler {
	private BufferedReader br;
	private String[] columns;
	private String line;
	private String contactName;
	private String subject;
	private String description;
	private String date;
	private boolean firstTime = true;
	private boolean crawl;

	private ArrayList<ForumTag> tags;

	public BugCrawler(ForumFactory fac, ParserPipeline pp,
			PostBucket crawlerBucket, String inputPath) throws IOException {
		super("Bug", fac, pp, crawlerBucket);

		br = new BufferedReader(new FileReader(inputPath));
		columns = br.readLine().split(";");
		line = "NoLine";
		subject = "NoSubject";
		description = "NoDescription";
		date = "NoDate";
		crawl = true;
	}

	@Override
	protected List<ForumPost> crawl() throws Exception {
		List<ForumPost> posts = new ArrayList<ForumPost>();
		tags = new ArrayList<ForumTag>();

		while ((line = br.readLine()) != null) {
			crawl = true;
			String[] splitLine = line.split(";");
			if (splitLine.length > 1 && isNumeric(splitLine[0])) {
				if (!firstTime) {
					posts = makeBugPost();
				}
				// Contact Name
				contactName = splitLine[1].equals("") ? "NoPoster"
						: splitLine[1];
				// Date
				date = splitLine[2];

				// Get all tags
				for (int i = 3; i <= columns.length - 3; i++) {
					if (splitLine[i].equals("")) {
						continue;
					}
					tags.add(fac.makeTag(splitLine[i]));
				}

				// Subject
				if (splitLine.length <= (columns.length - 2)) {
					subject = "NoSubject";
				} else {
					subject = splitLine[(columns.length - 2)];
				}

				// Description
				if (splitLine.length <= (columns.length - 1)) {
					description = "";
				} else {
					description = splitLine[(columns.length - 1)];
				}
				if (!firstTime) {
					crawl = true;
					break;
				} else {
					firstTime = false;
				}
			} else {
				description = description.concat(line);
			}
		}
		if (posts.isEmpty()) {
			posts = makeBugPost();
		}
		return posts;
	}

	private List<ForumPost> makeBugPost() {
		List<ForumPost> posts = new ArrayList<ForumPost>();

		description = description.replaceAll("-SEMICOLON-", ";");

		if (description.startsWith("\"")) {
			description = description.substring(1);
		}
		if (description.endsWith("\"")) {
			description = description.substring(0, description.length() - 1);
		}
		subject = subject.replaceAll("-SEMICOLON-", ";");
		ParserAnnotation pa = pp.make(description);
		posts.add(fac.makePost(subject, pa, "BugCrawler", contactName, date,
				"00:00:00", "NoLink", "NoCategory", tags));

		return posts;
	}

	@Override
	public void close() throws Exception {
		br.close();
	}

	private boolean isNumeric(String number) {
		try {
			Integer.parseInt(number);
			return true;
		} catch (Exception e) {
			return false;
		}
	}

	@Override
	public boolean canCrawl() {
		if (line == null) {
			return false;
		}
		return crawl;
	}
}
